﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Buffer = System.Buffer;

namespace Wazzup.Engine.Utility
{
    public static class EncryptionHelper
    {
        public static byte[] HexStringToByteArray(String hex)
        {
            try
            {
                int numberChars = hex.Length;
                byte[] bytes = new byte[numberChars / 2];
                for (int i = 0; i < numberChars; i += 2)
                    bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
                return bytes;
            }
            catch (Exception)
            {
                return null;
            }
        }
        public static RC4EncHelper EncryptionOutgoing = null;
        public static RC4EncHelper EncryptionIncoming = null;

        public static byte[] WhatsappEncrypt(byte[] key, byte[] data, bool appendHash)
        {
            if (EncryptionOutgoing == null)
                EncryptionOutgoing = new RC4EncHelper(key, 256);
            var h = new HMACSHA1(key);
            var buff = new byte[data.Length];
            Buffer.BlockCopy(data, 0, buff, 0, data.Length);

            EncryptionOutgoing.Cipher(buff);
            var hashByte = h.ComputeHash(buff);
            var response = new byte[4 + buff.Length];
            if (appendHash)
            {
                Buffer.BlockCopy(buff, 0, response, 0, buff.Length);
                Buffer.BlockCopy(hashByte, 0, response, buff.Length, 4);
            }
            else
            {
                Buffer.BlockCopy(hashByte, 0, response, 0, 4);
                Buffer.BlockCopy(buff, 0, response, 4, buff.Length);
            }

            return response;
        }
        public static byte[] WhatsappDecrypt(byte[] key, byte[] data)
        {
            if (EncryptionIncoming == null)
                EncryptionIncoming = new RC4EncHelper(key, 256);
            var buff = new byte[data.Length];
            Buffer.BlockCopy(data, 0, buff, 0, data.Length);
            EncryptionIncoming.Cipher(buff);
            return buff;
        }

        public static string ComputeMd5(string str)
        {
            var alg = HashAlgorithmProvider.OpenAlgorithm("MD5");
            var buff = CryptographicBuffer.ConvertStringToBinary(str, BinaryStringEncoding.Utf8);
            var hashed = alg.HashData(buff);
            var res = CryptographicBuffer.EncodeToHexString(hashed);
            return res;
        }

        public static byte[] EncryptFile(Stream stream)
        {
            var alg = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha1);
            var inputBuffer = new byte[stream.Length];

            stream.Read(inputBuffer, 0, (int)stream.Length);
            var buff = CryptographicBuffer.CreateFromByteArray(inputBuffer);
            var hashed = alg.HashData(buff);
            var res = CryptographicBuffer.EncodeToHexString(hashed);
            return Encoding.UTF8.GetBytes(res);
        }

        public static byte[] EncryptSha1(string s)
        {
            var alg = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha1);
            var inputBuffer = Encoding.GetEncoding("iso-8859-1").GetBytes(s);
            var buff = CryptographicBuffer.CreateFromByteArray(inputBuffer);
            var hashed = alg.HashData(buff);
            var res = CryptographicBuffer.EncodeToHexString(hashed);
            return Encoding.GetEncoding("iso-8859-1").GetBytes(res);
        }

        public static byte[] EncryptSha1(byte[] s)
        {
            var alg = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha1);
            //var inputBuffer = Encoding.GetEncoding("iso-8859-1").GetBytes(s);
            var buff = CryptographicBuffer.CreateFromByteArray(s);
            var hashed = alg.HashData(buff);
            var res = CryptographicBuffer.EncodeToHexString(hashed);
            return Encoding.GetEncoding("iso-8859-1").GetBytes(res);
        }

        public static string EncryptPassword(string password)
        {
            var binaryHash = Convert.FromBase64String(password);
            var res = Encoding.GetEncoding("iso-8859-1").GetString(binaryHash, 0, binaryHash.Length);
#if DEBUG
            System.Diagnostics.Debug.WriteLine("--- Enc Password : " + res);
#endif
            return res;

        }

        public static string Md5(string pass)
        {

            var dataMd5 = WhatsApp.SYSEncoding.GetBytes(ComputeMd5(pass));
            var sb = new StringBuilder();
            foreach (var t in dataMd5)
                sb.AppendFormat("{0:x2}", t);
            return sb.ToString();
        }
    }
}
